package objReader;

import java.io.BufferedReader;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Scanner;

public class ModelReader 
{
	static ArrayList<Vertex3> vertices; 	/* vt */
	static ArrayList<Vertex3> normals; 		/* vn */
	static ArrayList<Vertex2> texCoord;		/* vt */
	static ArrayList<Face> faces;			/* f */
	static ArrayList<Material> materials;	/* materials used by model */
	static ArrayList<objModel> objects;
	
	static ArrayList<Vertex3> arr;			/* tmp array */
	static int vertexCount;
	static int faceCount;
	static int objectCount;
	static String materialsFilename;
	
	/**/
	public static ArrayList<objModel> readModelFile(String filename)
	{
		/* Initialize data structures */
		texCoord = new ArrayList<Vertex2>();
		normals = new ArrayList<Vertex3>();
		vertices = new ArrayList<Vertex3>();
		faces = new ArrayList<Face>();
		arr = new ArrayList<Vertex3>();
		materials = new ArrayList<Material>();
		objects = new ArrayList<objModel>();
		
		objectCount = -1;
		faceCount = 0;
		vertexCount = 0;
		int matIndex = 0;
		
		BufferedReader fileReader = null;
		Scanner lineTokenizer = null;
		String line;
		
		/* obj Model to return */
		objModel model = null;

		try
		{
			fileReader = new BufferedReader(new FileReader(filename));
			
			/* Read line by line */
			while((line = fileReader.readLine()) != null)
			{
				/* Tokenize the line */
				lineTokenizer = new Scanner(line);
				
				if(line.length() <= 2) /* disregard lines that contain less than 2 characters */
					continue;
				else if(line.contains("o ")) /* New object */
				{
					System.out.println("New object found. objCount = " + (objectCount + 2));

					lineTokenizer.next(); /* Disregard the first line */
					model = new objModel(lineTokenizer.next());
					objects.add(model);
					
					objectCount++;
				}
				else if(line.contains("mtllib ")) /* Materials library file */
				{
					lineTokenizer.next(); /* disregard the 1st string (or token) */
					materialsFilename = lineTokenizer.next();
					
					materials = MaterialReader.readMaterialFile("src/data/models/" + materialsFilename/*, objects.get(objectCount)*/); /* Populate materials */
				}
				else if(line.contains("usemtl "))
				{
					lineTokenizer.next();
					
					/* Update material index */
					matIndex = MaterialReader.getIndexOfMaterialWithName(lineTokenizer.next(), materials);
					objects.get(objectCount).materialIndex = matIndex;
					if(materials.get(matIndex).usesTexture)
						objects.get(objectCount).setTexture(materials.get(matIndex).getTexture());
				}
				else if(line.contains("v ")) /* vertices */
				{
					lineTokenizer.next(); /* disregard the 1st string */
					vertices.add(new Vertex3(lineTokenizer.nextFloat(),
																	  lineTokenizer.nextFloat(),
																	  lineTokenizer.nextFloat()));
				}
				else if(line.contains("vt ")) /* texCoord */
				{
					lineTokenizer.next(); /* disregard the 1st string */
					texCoord.add(new Vertex2(lineTokenizer.nextFloat(),
											 						  lineTokenizer.nextFloat()));
				}
				else if(line.contains("vn ")) /* normals */
				{
					lineTokenizer.next(); /* disregard the 1st string */
					normals.add(new Vertex3(lineTokenizer.nextFloat(),
																	 lineTokenizer.nextFloat(),
																	 lineTokenizer.nextFloat()));
				}
				else if(line.contains("f "))
				{
					lineTokenizer.next(); /* disregard the 1st string */
					objects.get(objectCount).faceIndices.add(new Face(lineTokenizer.next(),
																      lineTokenizer.next(),
																      lineTokenizer.next(),
																      matIndex));
				}
			}
			
			/* Close the file readers */
			try
			{
				if(lineTokenizer != null)
					lineTokenizer.close();
				
				if(fileReader != null)
					fileReader.close();
			}
			catch(Exception e)
			{
				System.out.println("Error closing file: '" + e.toString() + "'. ");
			}
		}
		catch(Exception ioe)
		{
			System.out.println("Error opening file ("+ filename + "): '" + ioe.toString() + "'.");
		}
		
		/* Set the vertices, normals, and texture arrays */
		//model.vertices = vertices;
		//model.normals = normals;
		//model.texCoord = texCoord;
		//model.faceIndices = faces;
		//model.materials = materials;
		
		return objects; /* return true if model successfully read */
	}
	
	/**/
	public static int parseFaceData(String token)
	{
		return Integer.parseInt(token.substring(0, token.indexOf('/')));
	}
	
}


